<?php

define ('kLdCodePath', 
	kLdLibraryPath .
	DIRECTORY_SEPARATOR . 'Code'
);
define ('kLdCachesPath',
	kLdLibraryPath .
	DIRECTORY_SEPARATOR . '__Caches'
);

if (!is_dir(kLdCachesPath))
	mkdir(kLdCachesPath, 0700, false);

function __autoload($class) {
	LdInclude($class);
}

// =================
// = Loader basics =
// =================

/**
 * Classes implementing this interface can be added to the loading
 * system through LdAddLoader() to extend the loading system.
 */
interface ILdLoader {
	/**
	 * Makes a class available to the current environment if possible.
	 *
	 * @param name The name of the class to be loaded.
	 * @return <code>true</code> if the class was found and loaded, <code>false</code> otherwise.
	 */
	function includeClassWithName($name);
}



/**
 * @private
 */
$GLOBALS['_LdCallables'] = array();

/**
 * Adds a loader to the global list of loaders.
 * @param item The item to be added. It can be a callable of the form <code>function ...($className)</code> that returns a boolean, an object implementing the LdLoader interface, or a class name of a class implementing the LdLoader interface (of which a new instance will be created).
 */
function LdAddLoader($item) {
	if (is_object($item) && $item instanceof ILdLoader)
		$item = array($item, 'includeClassWithName');
	else if (is_string($item) && class_exists($item))
		$item = array(new $item(), 'includeClassWithName');
	else if (!is_callable($item))
		throw new Exception("Can't register non-callable, non-class, non-LdLoader extension to loader ($item)");
	
	$GLOBALS['_LdCallables'][] = $item;
}

/**
 * Requires that a class be loaded through the loading system.
 * 
 * Usually, you will not need to call this function directly as it
 * is called by the loader framework automatically when
 * classes are required.
 *
 * Requiring an already-loaded class will not throw an exception.
 * 
 * @param class The name of the class to be loaded.
 * @throws LdException if the class could not be found or loaded.
*/
function LdRequire($class) {
	if (!LdInclude($class))
		throw new LdException("Cannot find class $class using any loader plug-in.");
}

/**
 * Loads a class if not already loaded by looking for it through
 * the loading system.
 * 
 * @param class The name of the class to be loaded.
 * @return <code>true</code> if the class is available or has been loaded, <code>false</code> otherwise.
 */
function LdInclude($class) {
	if (class_exists($class))
		return true;
	
	foreach ($GLOBALS['_LdCallables'] as $callable) {
		if (call_user_func($callable, $class))
			break;
	}
	
	return class_exists($class);
}


/**
 * Thrown if a required class could not be loaded.
 */
class LdException extends Exception {}

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'KitsLoader.php';

/** Loads a kit that is available in the include path. */
function LdRequireKit($kit) {
	require_once "$kit/_Kit.php";
}

?>